from django.db.models import Sum, Max, Min, Count, Avg
from rest_framework.mixins import UpdateModelMixin, CreateModelMixin, RetrieveModelMixin, ListModelMixin, \
    DestroyModelMixin
from rest_framework.response import Response
from rest_framework import serializers
from django_filters.rest_framework import DjangoFilterBackend, FilterSet, CharFilter
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.viewsets import GenericViewSet

from apps.minapp.models import OrderGoods, OrderInfo, User, Detail, Cover, Window, Record_Day, Admins
import datetime
from dateutil.parser import parse


class UserSerializers(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'studentid']
        depth = 2


class UserSerializers1(serializers.ModelSerializer):
    avatar = serializers.CharField()

    class Meta:
        model = User
        fields = ['name', 'avatar', 'studentid', 'gender', 'age', 'phone', 'email']
        depth = 1


class AdminsSerializers(serializers.ModelSerializer):
    class Meta:
        model = Admins
        fields = ['id', 'studentid']
        depth = 2


class DetailSerializers(serializers.ModelSerializer):
    price = serializers.SerializerMethodField()
    name = serializers.SerializerMethodField()

    class Meta:
        model = Detail
        fields = ['cover_id', 'price', 'shop_id', 'name']
        depth = 2

    def get_price(self, obj):
        return obj.cover.price

    def get_name(self, obj):
        return obj.cover.name


class OrderGoodsSerializers(serializers.ModelSerializer):
    detail = DetailSerializers()

    class Meta:
        model = OrderGoods
        fields = ['score', 'detail']
        depth = 2


class ShopSerializers(serializers.ModelSerializer):
    class Meta:
        model = Window
        fields = ['title', 'position']
        depth = 1


class UserSeriaizers2(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['role']
        depth = 1


class OrderInfoSerializers(serializers.ModelSerializer):
    ordergoods = OrderGoodsSerializers(many=True)

    class Meta:
        model = OrderInfo
        fields = ['ordergoods']
        depth = 2


class OrderInfoSerializers1(serializers.ModelSerializer):
    ordergoods = OrderGoodsSerializers(many=True)
    shop = ShopSerializers()

    class Meta:
        model = OrderInfo
        fields = ['ordergoods', 'created_time', 'total_count', 'total_amount', 'shop']
        depth = 2


class UserSerializers(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['role']
        depth = 1


class OrderUserInfoSerializers(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()

    class Meta:
        model = OrderInfo
        fields = ['user']
        depth = 1

    def get_user(self, obj):
        return obj.user_id.role


class RecordSerializers(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()

    class Meta:
        model = Record_Day
        fields = ['record_time', 'name', 'sales', 'amount', 'value']
        depth = 1

    def get_name(self, obj):
        return obj.good.name


# 分析订单
def order_anlysis():
    orderInfo = OrderInfo.objects.get(id=1)
    data = OrderInfoSerializers(instance=orderInfo).data
    ordergoods = data['ordergoods']
    for ordergood in ordergoods:
        detail = ordergood['detail']
        record = Record_Day.objects.filter(good_id=detail['cover_id'],
                                           record_time=datetime.datetime.now().date()).first()
        if record:
            record.sales += 1
            record.amount += float(detail['price'])
            record.value = (record.value * (record.sales - 1) + float(ordergood['score'])) / record.sales
        else:
            record = Record_Day(good_id=detail['cover_id'], shop_id=detail['shop_id'], sales=1,
                                value=ordergood['score'],
                                amount=detail['price'])
        record.save()


# 分析queryset
def record_queryset_analysis(queryset):
    # 返回店铺总体数据
    data = list(queryset.aggregate(Sum('sales'), Sum('amount'), Avg('value')).values())
    # 返回店铺商品数据
    timeList = []
    nameList = []
    salesList = []
    amountsList = []
    valueList = []
    records = RecordSerializers(instance=queryset, many=True).data
    for record in records:
        timeList.append(record['record_time'])
        nameList.append(record['name'])
        salesList.append(record['sales'])
        amountsList.append(record['amount'])
        valueList.append(record['value'])
    return {'data': data, "timeList": timeList, "nameList": nameList, "salesList": salesList,
            "amountsList": amountsList,
            "valueList": valueList}


# 分析用户
def user_analalysis(users):
    value = [4, 5, 6, 7]
    user_role = ["本科生", '研究生', '教师', '其他人员']
    roles = []
    for user in users:
        if user['user'] == '本科生':
            value[0] += 1
        elif user['user'] == '研究生':
            value[1] += 1
        elif user['user'] == '教师':
            value[2] += 1
        else:
            value[3] += 1
    for i in range(0, len(value)):
        roles.append({"name": user_role[i], "value": value[i]})
    return roles


# 分析记录
def record_shop_anlysis(shop_id, start_date, end_date, compare_date):
    # 获得选定时间段的数据记录
    queryset = Record_Day.objects.filter(shop_id=shop_id, record_time__range=(start_date, end_date)).order_by(
        'good_id')
    # 分析提取所需数据
    dic = record_queryset_analysis(queryset)
    # 获得对比时间段的数据记录
    compareset = Record_Day.objects.filter(shop_id=shop_id, record_time__range=(compare_date, start_date)).order_by(
        'good_id')
    # 分析提取所需数据
    dic_cmp = record_queryset_analysis(compareset)
    users = OrderUserInfoSerializers(instance=
                                     OrderInfo.objects.filter(shop_id=shop_id, status=5,
                                                              orderok_time__range=(start_date, end_date)),
                                     many=True).data

    users_cmp = OrderUserInfoSerializers(instance=
                                         OrderInfo.objects.filter(shop_id=shop_id, status=5,
                                                                  orderok_time__range=(compare_date, start_date)),
                                         many=True).data
    roles = user_analalysis(list(users))

    dic['roles'] = roles
    # 数据对比
    shopdata = dic['data']
    shopdata.insert(0, len(users))
    dic['data'] = shopdata
    shopdata_cmp = dic_cmp['data']
    shopdata_cmp.insert(0, len(users_cmp))

    compare = []
    for i in range(0, len(shopdata_cmp)):
        gap = shopdata[i] / shopdata_cmp[i]
        isUp = gap >= 1
        if isUp:
            gap = format(gap - 1, ".2%")
        else:
            gap = format(1 - gap, ".2%")
        compare.append({'gap': gap, 'isUp': isUp})
    dic['compare'] = compare
    return dic


def record_good_anlysis(good_id, start_date, end_date, compare_date):
    # 获得选定时间段的数据记录
    queryset = Record_Day.objects.filter(good_id=good_id, record_time__range=(start_date, end_date))
    # 分析提取所需数据
    dic = record_queryset_analysis(queryset)
    # 获得对比时间段的数据记录
    compareset = Record_Day.objects.filter(good_id=good_id, record_time__range=(compare_date, start_date))
    # 分析提取所需数据
    dic_cmp = record_queryset_analysis(compareset)
    users = OrderUserInfoSerializers(instance=
                                     OrderInfo.objects.filter(goods__in=[good_id], status=5,
                                                              orderok_time__range=(start_date, end_date)),
                                     many=True).data

    users_cmp = OrderUserInfoSerializers(instance=
                                         OrderInfo.objects.filter(goods__in=[good_id], status=5,
                                                                  orderok_time__range=(compare_date, start_date)),
                                         many=True).data
    roles = user_analalysis(list(users))

    dic['roles'] = roles
    # 数据对比
    gooddata = dic['data']
    gooddata.insert(0, len(users))
    dic['data'] = gooddata
    gooddata_cmp = dic_cmp['data']
    gooddata_cmp.insert(0, len(users_cmp))
    print(gooddata)
    print(gooddata_cmp)
    compare = []
    for i in range(0, len(gooddata_cmp)):
        gap = gooddata[i] / gooddata_cmp[i]
        isUp = gap >= 1
        if isUp:
            gap = format(gap - 1, ".2%")
        else:
            gap = format(1 - gap, ".2%")
        compare.append({'gap': gap, 'isUp': isUp})
    dic['compare'] = compare
    return dic


def consume_analysis(consumes):
    activities = []
    records = []
    goods = []
    sales = []
    costs = []
    canteens = ["学子食堂", "学苑食堂", "留学生餐厅", "欧雅轩西餐厅"]
    visits = [0, 0, 0, 0]
    cv = []
    conclusion = [0, 0, 0]
    shoplist = []
    for consume in consumes:
        amount = consume['total_amount']
        conclusion[0] += float(amount)
        time = consume['created_time']
        time = parse(time).strftime("%Y-%m-%d %H:%M:%S")
        shop = consume['shop']
        if shop not in shoplist:
            shoplist.append(shop)
            conclusion[1] += 1
        position = shop['position']
        title = shop['title']
        activities.append(time)
        activities.append({'content': position + title + '消费:￥' + amount, "timestamp": time})
        record = position + title
        ordergoods = consume['ordergoods']
        for ordergood in ordergoods:
            detail = ordergood['detail']
            name = detail['name']
            price = detail['price']
            tmp = name + "     " + str(price)
            records.append({'content': record + tmp, "timestamp": time})
            if name not in goods:
                goods.append(name)
                sales.append(1)
                costs.append(price)
            else:
                pos = goods.index(name)
                sales[pos] = sales[pos] + 1
                costs[pos] = costs[pos] + price

        if '学子' in position:
            visits[0] += 1
        elif '学苑' in position:
            visits[1] += 1
        elif '留学生' in position:
            visits[2] += 1
        else:
            visits[3] += 1
    for i in range(0, len(visits)):
        cv.append({"name": canteens[i], "value": visits[i]})
    conclusion[2] = sum(sales)
    return {'goods': goods, 'sales': sales, 'costs': costs, 'canteens': cv, 'activities': activities,
            'records': records, 'conclusion': conclusion}


def user_consume_analysis(user_id, start_date, end_date):
    dic = {}
    user = UserSerializers1(User.objects.get(id=user_id)).data
    dic['user'] = user
    orderqueryset = OrderInfo.objects.filter(user_id_id=user_id, status=5)
    consumes = OrderInfoSerializers1(instance=orderqueryset, many=True).data
    dic['consumes'] = consumes
    analysis = consume_analysis(consumes)
    dic['analysis'] = analysis
    return dic


class ShopReport(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin,
                 DestroyModelMixin, GenericViewSet):
    def list(self, request, *args, **kwargs):
        # 获得前端请求数据
        Request = request.data
        shop_id = Request['shop_id']
        date_pick = Request['date_pick']
        # 划分时间段
        start_date = parse(date_pick[0]).date()
        end_date = parse(date_pick[1]).date()
        pierod = (end_date - start_date).days
        if pierod == 0:
            pierod = 1
        end_date = start_date + datetime.timedelta(days=pierod)
        compare_date = start_date - datetime.timedelta(days=pierod)
        report = record_shop_anlysis(shop_id, start_date, end_date, compare_date)

        return Response(report)


class GoodReport(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin,
                 DestroyModelMixin, GenericViewSet):
    def list(self, request, *args, **kwargs):
        # 获得前端请求数据
        Request = request.data
        good_id = Request['good_id']
        date_pick = Request['date_pick']
        # 划分时间段
        start_date = parse(date_pick[0])
        end_date = parse(date_pick[1])
        pierod = (end_date - start_date).days

        if pierod == 0:
            pierod = 1
        end_date = start_date + datetime.timedelta(days=pierod)
        compare_date = start_date - datetime.timedelta(days=pierod)
        record = record_good_anlysis(good_id, start_date, end_date, compare_date)
        report = record
        return Response(report)


class UserReport(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin,
                 DestroyModelMixin, GenericViewSet):
    def list(self, request, *args, **kwargs):
        # 获得前端请求数据
        Request = request.data
        user_id = Request['user_id']
        date_pick = Request['date_pick']
        # 划分时间段
        start_date = parse(date_pick[0]).date()
        end_date = parse(date_pick[1]).date()
        data = user_consume_analysis(user_id, start_date, end_date)
        return Response(data)
